package com.gbr.client.view;

import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import javafx.util.Callback;

import com.gbr.application.model.Capture;
import com.gbr.client.presentation.IDesktopPresentation;

public class CaptureListDelegate implements PropertyChangeListener {
    private IDesktopPresentation    presentation = null;
    private ListView<Capture>       listView     = null;
    private ObservableList<Capture> data         = null;

    public CaptureListDelegate(IDesktopPresentation prez) {
        presentation = prez;
        data = FXCollections.observableArrayList();
        presentation.addPropertyChangeListener(this);
    }

    public ListView<Capture> getList() {
        listView = new ListView<>(data);
        listView.setCellFactory(new Callback<ListView<Capture>, ListCell<Capture>>() {
            @Override
            public ListCell<Capture> call(ListView<Capture> list) {
                return new CaptureCell();
            }
        });
        listView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Capture>() {
            @Override
            public void changed(ObservableValue<? extends Capture> value, Capture oldValue, Capture newValue) {
                presentation.changeCaptureSelection(newValue, oldValue);
            }
        });
        return listView;
    }

    @Override
    public void propertyChange(final PropertyChangeEvent evt) {
        String property = evt.getPropertyName();
        if (property.equals(IDesktopPresentation.ADD)) {
            System.out.println("GUI received add..." + evt.getNewValue());
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    data.add((Capture) evt.getNewValue());
                }
            });
        } else if (property.equals(IDesktopPresentation.REMOVE)) {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    data.remove((Capture) evt.getNewValue());
                }
            });
        }
        if (property.equals(IDesktopPresentation.CAPTURE_SELECTION_CHANGED)) {
            final Capture newValue = (Capture) evt.getNewValue();
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    listView.getSelectionModel().select(newValue);
                }
            });
        }
    }

    class CaptureCell extends ListCell<Capture> {
        @Override
        public void updateItem(Capture capture, boolean empty) {
            super.updateItem(capture, empty);

            if (capture != null) {
                HBox hBox = new HBox();
                hBox.setPadding(new Insets(2.5));
                hBox.setSpacing(5);
                // hBox.setAlignment(Pos.CENTER);

                try {
                    BufferedImage img = capture.getFrames().get(0).getImage();
                    ImageView imageView = new ImageView(SwingFXUtils.toFXImage(img, null));
                    imageView.setFitWidth(50);
                    imageView.setPreserveRatio(true);
                    imageView.setSmooth(true);
                    imageView.setCache(true);
                    hBox.getChildren().add(imageView);

                    hBox.getChildren().add(new Text(capture.getId()));
                } catch (Exception e) {
                    e.printStackTrace();
                }

                setGraphic(hBox);
            }
        }
    }
}
